package demo.thread;


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author : feixiang.li
 * @since : 2025-09-18 09:37
 */
public class MyThreadPool {


    // 第一种写法的问题。就是当runnable没有数据的时候，线程会一直空转，不会自己停止
//    List<Runnable> runnableList = new ArrayList<>();
//    Thread thread1 = new Thread(() -> {
//        while (true) {
//            try {
//                if (runnableList.size() > 0) {
//                    runnableList.remove(0).run();
//                }
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//    });
    BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<>(1024);
    List<Thread> threadList = new ArrayList<>();
    private int corePoolSize = 10;

    private final RejectHandle rejectHandle;

    private int maxSize = 16;

    private int maxWaitTime = 1000;

    private TimeUnit timeUnit = TimeUnit.MILLISECONDS;

    public MyThreadPool(int corePoolSize, int maxSize, int maxWaitTime, TimeUnit timeUnit,
                        BlockingQueue<Runnable> blockingQueue,
                        RejectHandle rejectHandle
    ) {
        this.corePoolSize = corePoolSize;
        this.maxSize = maxSize;
        this.maxWaitTime = maxWaitTime;
        this.timeUnit = timeUnit;
        this.blockingQueue = blockingQueue;
        this.rejectHandle = rejectHandle;
    }

    private final Lock lock = new ReentrantLock();

    List<Thread> subThreadList = new ArrayList<>();

    public void execute(Runnable runnable) {
        lock.lock();
        try {
            // 当线程数小于核心线程数时，创建线程
            if (threadList.size() < corePoolSize) {
                Thread thread = new CoreThread();
                thread.start();
                threadList.add(thread);
            }
            if (blockingQueue.offer(runnable)) {
                System.out.println("加入队列成功");
                return;
            }
            // 当线程数大于核心线程数时，创建线程
            if (corePoolSize + subThreadList.size() < maxSize) {
                Thread thread = new SubCoreThread(String.valueOf(subThreadList.size() + 1));
                thread.start();
                subThreadList.add(thread);
            }
            System.out.println("当前线程数:" + threadList.size() + "辅助线程" + subThreadList.size() + "队列长度" + blockingQueue.size());
            if (!blockingQueue.offer(runnable)) {
                rejectHandle.reject(runnable, this);
            } else {
                System.out.println("加入队列成功2");
            }
        } finally {
            lock.unlock();
        }
    }

    class SubCoreThread extends Thread {

        // 构造方法：接收线程名称参数
        public SubCoreThread(String name) {
            super("辅助线程-" + name); // 调用父类Thread的构造方法设置名称
        }

        @Override
        public void run() {
            while (true) {
                try {
                    System.out.println("辅助线程抢占任务");
                    Runnable command = blockingQueue.poll(maxWaitTime, timeUnit);
                    if (command == null) {
                        System.out.println("辅助线程结束");
                        break;
                    }
                    System.out.println("辅助线程执行任务");
                    command.run();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    class CoreThread extends Thread {
        @Override
        public void run() {
            while (true) {
                try {
                    Runnable take = blockingQueue.take();
                    take.run();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
